define('apps/common/FriendRichInput', ['core/jQuery', 'core/ajax/Ajax', 'core/List', 'core/RichInput', 'core/ScrollBar', 'apps/common/Suggestion', 'core/Toggle', 'apps/common/UserData'], function(require) {
    
    var $ = require('core/jQuery'),
        List = require('core/List'),
        RichInput = require('core/RichInput'),
        Suggestion = require('apps/common/Suggestion'),
        UserData = require('apps/common/UserData'),
        Toggle = require('core/Toggle'),
        ScrollBar = require('core/ScrollBar'),
        Ajax = require('core/ajax/Ajax'),
        
        URL = {
            'friendsuggestion' : '/friend/ajax/friend_suggest.php',
            'friendpanel' : '/friend/ajax/pagelet_friend_list.php'
        },
        
        TPL = {
            'friendpanel' : '<div class="ui_frd_wrap abs" style="right:0">\
                                <div class="ui_list list_circle _j_grouplist dn"><ul class="ui_list_bd" style="max-height:130px"></ul></div>\
                                <div class="r slct_all"><a href="#" class="_j_selectall">全选</a></div>\
                                <ul class="ui_frd_title fix _j_title">\
                                    <li class="on _j_paneltype" data-paneltype="all"><a class="first" href="#"><span class="text _j_grouptext">全部好友</span><span class="ui_status b_arrow"><i class="status_item _j_groupdropdown"><i class="i_arrow"></i></i></span></a></li>\
                                    <li data-paneltype="recent" class="_j_paneltype"><a href="#"><span class="text">最近联系人</span></a></li>\
                                </ul>\
                                <div class="clear"></div>\
                                <div class="ui_frd_list _j_content" style="max-height:108px"><ul></ul></div>\
                            </div>'
        },
        
        // suggest类型
        TYPE_USER = 0, TYPE_GROUP = 1,
        
        mix = K.mix;
    
    function FriendRichInput(opts) {
        this.wrap = null; // 整个外包，用来存放生成的suggest list及所有好友的panel
        this.richInputCnt = null; // 好友富文本框cnt
        this.friendCnt = null; // 好友富文本框保存选中好友项的cnt
        this.friendInput = null; // 好友富文本框的input
        this.friendDropArrow = $(); // 所有好友展开的按钮
        this.withGroup = 0; // 设置suggest group（有没有分组）
        this.placeholder = undefined; // 伪placeholder元素
        this.type = 0; // 使用的类型：@(0)、私信(1)、加好友到私信群(2)、加好友到分组(3)、推荐宝贝给好友(4)
        this.limit = 0; // 好友input中的好友数上限（0代表无限制）
        this.reachLimit = false; // 是否到达上限
        this.selectedMode = false; // 是否刚刚选择了好友，刚刚选择完不该再出suggestion
        this.locked = false;
        mix(this, opts);
        
        K.CustEvent.createEvents(this, 'reachlimit,changeinput'); // 添加或删除好友动作释放
        
        this.friendData = {};
        this.init();
    }
    
    FriendRichInput.prototype = {
        
        'init' : function() {
            this.initList();
            this.initRichInput();
            this.suggestion = new Suggestion({'URL' : URL.friendsuggestion});
            this.bindEvents();
        },
        
        'initList' : function() {
            var _this = this;
            this.list = new List({
                'trigger' : this.friendInput,
                'createContainer' : function(data) {
                    this.container = $('<div class="ui_list list_suggest dn"></div>').appendTo(_this.richInputCnt);
                },
                
                'getValue' : function() {
                    var nowfocusItem = this.container.find(this.itemSelector+'.'+this.itemHoverClass);
                    return {
                        'type' : nowfocusItem.data('type'),
                        'id' : nowfocusItem.data('id'),
                        'name' : nowfocusItem.data('name'),
                        'isfriend' : nowfocusItem.data('isfriend')
                    };
                },
                
                'updateList' : function(data) {
                    this.container.html(
                        '<ul class="ui_list_bd">' +
                        K.map(data, function(item) {
                            var html;
                            if(parseInt(item.type, 10) === TYPE_USER) {
                                var focusTag = '', remark = '', logo = '', limit = 26, showlimit = limit,
                                    viewName = item.disp_name ? item.name : item.nick, showName; // 显示真名或昵称
                                
                                // 重名显示头像信息
                                if(item.dup_name && item.logo) {
                                    logo = '<span class="ui_avatar"><img src="'+item.logo+'" width="15" height="15" /></span>';
                                }
                                
                                // 设置双向关注图标和备注信息
                                if(item.isfriend === 3 && _this.type === 3) {
                                    focusTag = '<i class="spr_icons i_refollow_color r"></i>';
                                }
                                
                                // 显示截断
                        		showName = K.subByte(viewName, limit+3, '...');
                        		showlimit = limit - K.byteLen(viewName);
                                
                                // 备注信息
                                if(item.remark) {
                                    remark = '<span class="c9" title="'+item.remark+'">('+K.subByte(item.remark, showlimit+3, '...')+')</span>';
                                }
                                
                                html = '<li class="_j_listitem" data-type="'+item.type+'" data-isfriend="'+item.isfriend+'" data-id="'+item.id+'" data-name="'+viewName+'"><a href="#">'+focusTag+showName+logo+remark+'</a></li>';
                            } else {
                                html = '<li class="_j_listitem" data-type="'+item.type+'" data-id="'+item.id+'" data-name="'+item.name+'"><a class="circle" href="#"><i class="spr_icons i_circle"></i>'+item.name+'<span class="c9">'+item.num+'</span></a></li>';
                            }
                            return html;
                        }).join('') + 
                        '</ul>'
                    );
                    this.container.find(this.itemSelector).first().addClass(this.itemHoverClass);
                    this.container.find(this.itemSelector).last().addClass('last');
                    _this.setSuggestPosition(this.trigger, this.container);
                }
            });
        },
        
        'setSuggestPosition' : function(input, droplist) {
            var position = input.position();
            droplist.css({ 'top' : this.richInputCnt.position().top + this.richInputCnt.outerHeight(), 'left' : position.left - 2 });
        },
        
        'initRichInput' : function() {
            var toUser = this.friendInput.data('touser'), // toUser格式：[{'type':0/1, 'id':'xxxx', 'name':'xxxx'}, {'type':0/1, 'id':'xxxx', 'name':'xxxx'}] 或者{'type':0/1, 'id':'xxxx', 'name':'xxxx'}
                initData = toUser ? [].concat(toUser) : [];
                
            K.forEach(initData, $.proxy(function(user) {
                this.friendData[user.type+'_'+user.id] = user;
            }, this));
            
            this.richInput = new RichInput({
                'input': this.friendInput,
                'richInput' : this.friendCnt,
                'initData' : initData,
                'parseItemHTML' : function(data) {
                    var html;
                    if(parseInt(data.type, 10) === TYPE_USER) {
                        html = '<span class="suggest_item _j_richInputItem" id="_j_frich'+data.type+'_'+data.id+'" data-type="'+data.type+'" data-id="'+data.id+'" uid="'+data.id+'"><span>'+data.name+'</span>&nbsp;<a title="删除" class="spr_icons i_close_s _j_richInputItemDel" href="#"></a></span>';
                    } else {
                        html = '<span class="suggest_item _j_richInputItem" id="_j_frich'+data.type+'_'+data.id+'" data-type="'+data.type+'" data-id="'+data.id+'"><span><i class="spr_icons i_circle"></i>'+data.name+'</span>&nbsp;<a title="删除" class="spr_icons i_close_s _j_richInputItemDel" href="#"></a></span>';
                    }
                    return html;
                }
            });
            
            // 锁定不让用户输入
            if(this.locked) { this.friendInput.hide(); }
        },
        
        'bindEvents' : function() {
            var list = this.list,
                input = this.friendInput;
            list.on('outputvalue', $.proxy(this.selectSuggestFriend, this));
            input.bind('focus', $.proxy(this.listenInput, this));
            input.listenInput($.proxy(this.listenInput, this));
            input.bind('keydown', $.proxy(this.listenInputKey, this));
            this.friendDropArrow.click($.proxy(this.toggleFriendPanel, this));
            this.richInput.on('additem', $.proxy(this.syncAddFriend, this));
            this.richInput.on('delitem', $.proxy(this.syncDelFriend, this));
            this.richInputCnt.click($.proxy(this.focusInput, this));
            
            this.on('changeinput', $.proxy(function() {
                if(this.richInput.data.length > 0) {
                    this.placeholder && this.placeholder.hide();
                }
            }, this));
            
            // 当richinput彻底失去焦点时的动作控制
            new Toggle({
                'trigger' : this.richInput,
                'board' : this.richInputCnt,
                'handler' : $.proxy(function() {
                    if(!this.richInput.data.length && $.trim(this.friendInput.val()) === '') { // 当richinput无内容时，显示placeholder
                        this.placeholder && this.placeholder.show();
                    }
                    
                    // 清除用户输入区内容
                    this.suggestion.stop();
                    this.friendInput.val('');
                    this.hideEmptyTip();
                    
                    this.wrap.removeClass('suggest_focus');
                    if(!this.list.mouseon) { this.list.hide(); }
                    this.selectedMode = false;
                }, this)
            });
        },
        
        'selectSuggestFriend' : function(args) {
            this.friendInput.val('');
            this.list.hide();
            this.addFriend(args);
            this.selectedMode = true;
        },
        
        'focusInput' : function() {
            if(!this.locked) {
                this.friendInput.focus();
            }
        },
        
        /**
         * 初始化时加入好友
         */
        'addInitFriend' : function(users) {
            K.forEach(users, $.proxy(function(user) {
                this.addFriend({'data':user});
            }, this));
        },
        
        'addFriend' : function(args) {
            var data = args.data,
                key = data.type+'_'+data.id;
            
            if(this.friendData[key]) {
                this.notifyDuplicate(key);
            } else if(this.reachLimit) {
                this.fire('reachlimit');
            } else {
                this.friendData[key] = data;
                this.richInput.addItem(data);
            }
        },
        
        'notifyDuplicate' : function(key) {
            var target = $('#_j_frich'+key);
            target.animate({'opacity':0.3}).animate({'opacity':1});
        },
        
        'delFriend' : function(uid) {
            var friendKey = TYPE_USER+'_'+uid,
                targetUserIndex = this.friendCnt.children('._j_richInputItem[uid="'+uid+'"]').index();
            this.friendData[friendKey] && delete this.friendData[friendKey];
            if(targetUserIndex !== -1) {
                this.richInput.delItem(targetUserIndex);
            }
        },
        
        'syncAddFriend' : function(args) {
            var data = args.data;
            if(parseInt(data.type, 10) === TYPE_USER && this.friendPanel) {
                this.friendPanel.find('._j_content ul input:checkbox[data-uid="'+data.id+'"]').prop('checked', true);
            }
            this.checkLimit();
            this.fire('changeinput');
        },
        
        'syncDelFriend' : function(args) {
            var data = args.data;
            if(parseInt(data.type, 10) === TYPE_USER) {
                var uid = data.id,
                    friendKey = TYPE_USER+'_'+uid;
                this.friendData[friendKey] && delete this.friendData[friendKey];
                this.friendPanel && this.friendPanel.find('._j_content ul input:checkbox[data-uid="'+uid+'"]').prop('checked', false);
            }
            this.checkLimit();
            this.fire('changeinput');
            this.selectedMode = true;
        },
        
        'suggestFriend' : function(inputVal) {
            var list = this.list,
                inputVal = $.trim(this.friendInput.val());
            
            // 当用户在最开始输入@时，直接忽略
            inputVal = inputVal.replace(/^@/, '');
            this.suggestion.getSuggestion({'key' : inputVal, 'withgroup' : this.withGroup, 'type' : this.type}, $.proxy(function(data) {
                if(data.list && data.list.length) {
                    this.hideEmptyTip();
                    list.show(data.list);
                } else {
                    this.showEmptyTip();
                    list.hide();
                }
            }, this));
        },
        
        'showEmptyTip' : function() {
            if(!this.emptyTip) {
            	var friendType = this.type == 3 ? '我的关注' : '互相关注';
                this.emptyTip = $('<div class="suggest_tip"><p class="c6">姓名不在“' + friendType + '”列表中，请重新输入</p></div>').insertAfter(this.richInputCnt);
            }
            this.emptyTip.css('top', this.wrap.outerHeight()-1).show();
        },
        
        'hideEmptyTip' : function() {
            this.emptyTip && this.emptyTip.hide();
        },
        
        'checkLimit' : function() {
            if(this.limit > 0) {
                if(this.richInput.data.length >= this.limit) {
                    this.reachLimit = true;
                } else {
                    this.reachLimit = false;
                }
            }
        },
        
        'listenInput' : function(ev) {
            var inputVal = $.trim(this.friendInput.val());
            
            if(inputVal || (this.type === 1 && ev.type === 'focus' && !this.selectedMode)) {
                this.suggestFriend();
            } else {
                this.list.hide();
            }
            
            if(ev.type === 'focus') {
                this.wrap.addClass('suggest_focus');
                this.placeholder && this.placeholder.hide();
            } else {
                this.selectedMode = false;
            }
            
        },
        
        'listenInputKey' : function(ev) {
            if(ev.keyCode === 8 && $(ev.currentTarget).val() === '') { // 删除为空时
                this.list.hide();
            } if(ev.keyCode === 40 && !this.list.visible) { // 向下键自动suggest
                this.suggestFriend();
            }
        },
        
        'toggleFriendPanel' : function(ev) {
            
            ev.preventDefault();
            
            // 锁定不让用户点开选择好友
            if(this.locked) { return }
            
            var target = $(ev.currentTarget);
            if(!this.friendPanel) {
                this.createFriendPanel();  // 第一次展开好友面板时，请求所有好友数据
                target.addClass('b_minus').removeClass('b_add');
            } else {
                
                // 切换panel的显隐，改变trigger的class
                this.friendPanel.toggle();
                if(this.friendPanel.is(':hidden')) {
                    target.addClass('b_add').removeClass('b_minus');
                } else {
                    target.addClass('b_minus').removeClass('b_add');
                    
                    // grouplist 重置（也可不重置，看产品策略）
                    this.friendPanelGroupCnt.addClass('dn');
                    this.groupListDropDown.removeClass('on');
                    this.resetAllSelector();
                }
            }
        },
        
        'createFriendPanel' : function() {
            var friendPanel = $(TPL.friendpanel).appendTo(this.wrap);
            this.friendPanel = friendPanel; // 好友面板
            this.friendPanelTitle = friendPanel.children('._j_title'); // 好友面板的tab title(全部好友，最近联系人)
            this.friendPanelContent = friendPanel.children('._j_content');  // 好友列表展示区
            this.friendPanelGroupCnt = friendPanel.children('._j_grouplist'); // 好友分组下拉框
            this.groupListDropDown = this.friendPanelTitle.find('._j_groupdropdown'); // 好友分组下拉触发按按钮
            this.allSelector = friendPanel.find('._j_selectall');
            friendPanel.show(); // 初次显示应该是loading状态
            
            Ajax.get(URL.friendpanel, 
            	{'type' : this.type},
            	$.proxy(function(data) {
                    this.friendPanelData = data.html; // 获取全部好友数据
                    this.setFriendPanel(); // 设置好友面板（主要是事件绑定）
                    this.showFriendList(); // 设置好面板之后，显示好友列表
	            }, this),
	            $.proxy(function(error) {
                    K.log('Data Err:', error);
	            }, this)
            );
        },
        
        /**
         * 绑定事件并初始化friend panel中的scroll bar
         */
        'setFriendPanel' : function() {
            
            // 好友分组列表下拉
            this.groupListDropDown.click($.proxy(this.toggleGroupList, this));
            
            // 按类型切换好友列表
            this.friendPanelTitle.children('._j_paneltype').click($.proxy(this.showTypeFriendList, this));
            
            // 按好友分组切换好友列表
            this.friendPanelGroupCnt.delegate('li', 'click', $.proxy(this.showGroupFriendList, this));
            
            // 选择（取消选择）一个好友
            this.friendPanelContent.delegate('input:checkbox', 'click', $.proxy(this.selectSingle, this));
            
            // 全选及全部取消按钮
            this.allSelector.click($.proxy(this.selectAll, this));

            // 设置好友列表的滚动条
            this.friendPanelBar = new ScrollBar({'container' : this.friendPanelContent});
            
            // 设置好友分组列表滚动条
            this.groupListBar = new ScrollBar({'container' : this.friendPanelGroupCnt.children('ul')});
            
            new Toggle({ // 点击body，收起friendpanel动作
                'trigger' : this.friendDropArrow,
                'board' : this.friendPanel,
                'handler' : function() {
                    this.board.hide();
                    this.trigger.removeClass('b_minus').addClass('b_add');
                }
            });
            
            new Toggle({ // 点击好友面板其他地方，好友分组下拉框消失
                'context' : this.friendPanel,
                'trigger' : this.groupListDropDown,
                'board' : this.friendPanelGroupCnt,
                'handler' : function() {
                    this.board.addClass('dn');
                }
            });
        },
        
        'resetFriendPanel' : function() {
            if(this.friendPanelGroupCnt) {
                this.friendPanelGroupCnt.children('li[data-group="0"]').trigger('click');
                this.setSelectedFriend();
            }
        },
        
        /**
         * 根据paneltype(两种：all - 全部好友, recent - 最近联系人)、group:全部好友中的分组,来显示好友列表
         */
        'showFriendList' : function(paneltype, group) {
            var friendList;
            paneltype = paneltype || 'all';
            group = group || 0; // 0 - all user
            if(!this.selectPanelType || this.selectPanelType !== paneltype) {
                this.friendPanelContent.children('ul').html(this.friendPanelData[paneltype]);
                this.setSelectedFriend(); // 初次载入数据或是切换数据类型时，重新设置面板中已被选中的好友
            }
            this.selectPanelType = paneltype;
            if(paneltype === 'all') { // 如果是全部好友类型，则根据当前好友分组显示对应分组的列表
                friendList = this.friendPanelContent.find('li');
                friendList.not('.group_' + group).hide();
                friendList.filter('.group_' + group).show();
            }
            
            this.resetAllSelector();
            this.friendPanelBar.fire('contentchange'); // 更新滚动条的长度
        },
        
        /**
         * 展开好友列表后，将当前已经选中的好友前的checkbox勾选
         */
        'setSelectedFriend' : function() {
            K.forEach(this.friendData, $.proxy(function(data) {
                if(parseInt(data.type) === TYPE_USER) {
                    this.friendPanelContent.find('input:checkbox[data-uid="'+data.id+'"]').prop('checked', true);
                }
            }, this));
        },
        
        'showTypeFriendList' : function(ev) {
            var target = $(ev.currentTarget), paneltype;
            if(!target.hasClass('on')) {
                paneltype = target.data('paneltype');
                this.showFriendList(paneltype, target.data('group'));
                target.siblings().removeClass('on');
                target.addClass('on');
                if(paneltype !== 'all') {
                    this.groupListDropDown.removeClass('on');
                }
            }
            ev.preventDefault();
        },
        
        'showGroupFriendList' : function(ev) {
            var target = $(ev.currentTarget), group, targetTitle;
            if(!target.hasClass('belong')) {
                group = target.data('group');
                this.showFriendList('all', group);
                target.siblings('.belong').removeClass('belong');
                target.addClass('belong');
                targetTitle = this.friendPanelTitle.children('._j_paneltype[data-paneltype="all"]');
                
                // 更换当前分组名
                //if(target.data('groupid') === 0) {
                targetTitle.find('._j_grouptext').text(target.data('groupname'));
                //} else {
                //    targetTitle.find('._j_grouptext').html('<i class="spr_icons i_circle"></i>'+target.data('groupname'));
                //}
                
                // 更新头部title数据，并且隐藏分组，重置下拉按钮
                if(!targetTitle.hasClass('on')) {
                    targetTitle.siblings().removeClass('on');
                    targetTitle.addClass('on');
                }
                this.friendPanelGroupCnt.addClass('dn');
                this.groupListDropDown.removeClass('on');
            }
            ev.preventDefault();
        },
        
        'toggleGroupList' : function(ev) {
            if(!this.groupList) {
                UserData.getFGroup($.proxy(function(data) {
                    var html = '<li class="belong" data-groupname="全部好友" data-group="0"><a href="#">全部好友<i class="spr_icons i_circle"></i></a></li>'+
                        K.map(data, function(group) {
                            return '<li data-groupname="'+group.gname+'" data-group="'+group.gid+'"><a href="#">'+group.gname+'<i class="spr_icons i_circle"></i></a></li>';
                        }).join('');
                    this.friendPanelGroupCnt.find('ul').html(html);
                    this.groupList = this.friendPanelGroupCnt.children('ul');
                    this.friendPanelGroupCnt.removeClass('dn');
                }, this));
            } else {
                this.friendPanelGroupCnt.toggleClass('dn');
            }
            $(ev.currentTarget).toggleClass('on');
            ev.preventDefault();
        },
        
        /**
         * 选择一个好友
         */
        'selectFriend' : function(target) {
            var visibleInput = this.friendPanelContent.find('input:visible');
            if(target.is(':checked')) {
                if(!this.reachLimit) {
                    this.addFriend({'data':{'type':TYPE_USER, 'id' : target.data('uid'), 'isfriend' : target.data('isfriend'), 'name':target.data('name')}});
                } else {
                    this.fire('reachlimit');
                    target.prop('checked', false);
                }
            } else {
                this.delFriend(target.data('uid'));
            }
            this.selectedMode = true;
        },
        
        /**
         * 选择一个好友
         */
        'selectSingle' : function(ev) {
            this.selectFriend($(ev.currentTarget));
            this.resetAllSelector();
        },
        
        /**
         * 全选
         */
        'selectAll' : function(ev) {
            var _this = this,
                target = $(ev.currentTarget);
            if(target.hasClass('_j_retrieve')) {
                target.removeClass('_j_retrieve').text('全选');
                this.friendPanelContent.find('input:checked:visible').each(function() {
                    $(this).prop('checked', false);
                    _this.selectFriend($(this));
                });
            } else {
                target.addClass('_j_retrieve').text('取消');
                var unchecked = this.friendPanelContent.find('input:visible').not(':checked');
                
                // 获取还可以添加的好友数
                if(this.limit) {
                    var limitLeave = this.limit - this.richInput.data.length;
                    unchecked = unchecked.slice(0, limitLeave);
                }
                unchecked.each(function() {
                    $(this).prop('checked', true);
                    _this.selectFriend($(this));
                });
            }
            ev.preventDefault();
        },
        
        'resetAllSelector' : function() {
            var visibleInput = this.friendPanelContent.find('input:visible');
            if(visibleInput.length) {
                this.allSelector.parent().removeClass('dn');
                if(visibleInput.not(':checked').length) {
                    this.allSelector.removeClass('_j_retrieve').text('全选');
                } else {
                    this.allSelector.addClass('_j_retrieve').text('取消');
                }
            } else {
                this.allSelector.parent().addClass('dn');
            }
        },
        
        'reset' : function() {
            this.friendData = {};
            this.richInput.empty();
            this.resetFriendPanel();
            this.checkLimit();
            this.fire('changeinput');
        },
        
        'getData' : function() {
            var friendData = {'fuids' : [], 'gids' : []};
            
            // 获取friends数据
            K.forEach(this.richInput.data, function(user) {
                if(parseInt(user.type, 10) === TYPE_USER) {
                    friendData.fuids.push(user.id);
                } else {
                    friendData.gids.push(user.id);
                }
            });
            
            return friendData;
        }
    };
    
    return FriendRichInput;
});
